module Maze
  class Point < Struct.new(:x, :y)

    def self.random(maze)
      new(rand(maze.width), rand(maze.height))
    end

    def out_of_bounds?(maze)
      !(x.between?(0, maze.width  - 1) && y.between?(0, maze.height - 1))
    end

    def unvisited?(maze)
      maze[self].nil?
    end

    def next(maze, direction)
      next_x = x + maze.calculate_offset_x_axis(direction, self)
      next_y = y + maze.calculate_offset_y_axis(direction, self)
      next_point = self.class.new(next_x, next_y)

      next_point.out_of_bounds?(maze) ? nil : next_point
    end

    def update
      other = self.dup
      yield other if block_given?
      other
    end

    def +(other)
      self.class.new(x + other.x, y + other.y)
    end

    def raw
      [x, y]
    end
  end
end

